import * as d3 from 'd3'
var BarChart = {
  data: '',
  divId: '',
  xLabel: '',
  yLabel: '',
  title: '',
  itemsName: [],
  barChart: {},
  color: d3.scaleOrdinal(d3.schemeCategory10),
  draw: function () {
    this.initChart()
    this.initAxis()
    this.drawLabel()
    this.drawBarChart()
  },
  update: function () {
    this.barChart.xScale.domain(d3.range(0, this.data.length))
    this.barChart.yScale.domain([0, d3.max(this.data, d => d.value)])
    this.barChart.xAxis.scale(this.barChart.xScale)
    this.barChart.yAxis.scale(this.barChart.yScale)
    this.barChart.svg.select('.xAxis').call(this.barChart.xAxis)
    this.barChart.svg.select('.yAxis').call(this.barChart.yAxis)
    this.barChart.barPadding = this.barChart.xScale.bandwidth() * 0.9
    this.drawBarChart()
  },
  initChart: function () {
    this.barChart.padding = {
      left: 20,
      right: 55,
      top: 25,
      bottom: 20
    }
    this.barChart.divHeight = document.getElementById(this.divId).offsetHeight -
      this.barChart.padding.top -
      this.barChart.padding.bottom
    this.barChart.divWidth = document.getElementById(this.divId).offsetWidth -
      this.barChart.padding.left -
      this.barChart.padding.right

    this.barChart.svg = d3.select('#' + this.divId)
      .append('svg')
      .attr('width', this.barChart.divWidth +
        this.barChart.padding.left +
        this.barChart.padding.right
      )
      .attr('height', this.barChart.divHeight +
        this.barChart.padding.top +
        this.barChart.padding.bottom
      )
      .attr('class', 'svg_barChart')
  },
  initAxis: function () {
    // 定义x轴的比例尺
    this.barChart.xScale = d3.scaleBand()
      .domain(this.data.map(d => d.name))
      .range([this.barChart.padding.left, this.barChart.divWidth])

    this.barChart.barPadding = this.barChart.xScale.bandwidth() * 0.9
    // 定义y轴的比例尺
    this.barChart.yScale = d3.scaleLinear()
      .domain([0, d3.max(this.data, d => d.value)])
      .range([this.barChart.divHeight, this.barChart.padding.top])
    // 定义x轴
    this.barChart.xAxis = d3.axisBottom()
      .scale(this.barChart.xScale)
    // 定义y轴
    this.barChart.yAxis = d3.axisLeft()
      .scale(this.barChart.yScale)

    this.barChart.svg.append('g')
      .attr('class', 'xAxis')
      .attr('transform', 'translate(0,' +
        this.barChart.divHeight + ')')
      .call(this.barChart.xAxis)

    this.barChart.svg.append('g')
      .attr('class', 'yAxis')
      .attr('transform', 'translate(' + this.barChart.padding.left + ')')
      .call(this.barChart.yAxis)
  },
  drawBarChart: function () {
    let bars = this.barChart.svg.selectAll('.gbar')
      .data(this.data, d => d.name)

    bars.select('rect')
      .transition()
      .duration(750)
      .delay(750)
      .attr('height', d => {
        return this.barChart.divHeight - this.barChart.yScale(d.value)
      })
      .attr('y', d => {
        return this.barChart.yScale(d.value)
      })
      .attr('x', (d, i) => {
        return this.barChart.xScale(i)
      })
      .attr('width', this.barChart.barPadding)

    bars.select('text')
      .transition()
      .duration(750)
      .delay(750)
      .attr('x', (d, i) => {
        return this.barChart.xScale(i) + this.barChart.barPadding * 0.3
      })
      .attr('y', d => {
        return this.barChart.yScale(d.value) - 10
      })
      .text(d => d.value)

    // 增加的DOM元素
    let barsEnter = bars
      .enter()
      .append('g')
      .attr('class', 'gbar')

    barsEnter.append('rect')
      .attr('x', (d, i) => {
        return this.barChart.xScale(i)
      })
      .attr('y', this.barChart.divHeight)
      .attr('width', this.barChart.barPadding)
      .attr('height', 0)
      .style('stroke', 'black')
      .style('fill', '#a8dadc')
      .on('mouseover', barMouseOver)
      .on('mouseout', barMouseOut)

    barsEnter.append('text')
      .attr('x', (d, i) => {
        return this.barChart.xScale(i) + this.barChart.barPadding * 0.3
      })
      .attr('y', this.barChart.divHeight)
      .style('font-size', 1e-6)
      .text(d => d.value)

    barsEnter.select('rect')
      .transition()
      .duration(750)
      .delay(750)
      .attr('height', d => {
        return this.barChart.divHeight - this.barChart.yScale(d.value)
      })
      .attr('y', d => {
        return this.barChart.yScale(d.value)
      })

    barsEnter.select('text')
      .transition()
      .duration(750)
      .delay(750)
      .style('font-size', 16)
      .attr('y', d => {
        return this.barChart.yScale(d.value) - 5
      })

    // 删除的Dom
    let barExit = bars.exit()
      .transition()
      .duration(750)
      .remove()

    barExit.selectAll('rect')
      .attr('y', this.barChart.divHeight)
      .attr('height', 0)

    barExit.selectAll('text')
      .style('font-size', 1e-6)

    function barMouseOver (d) {
      d3.select(this)
        .transition()
        .duration(500)
        .style('fill', '#023e8a')
    }

    function barMouseOut (d) {
      d3.select(this)
        .transition()
        .duration(500)
        .style('fill', '#a8dadc')
    }
  },
  sort: function () {
    this.barChart.svg.selectAll('.gbar')
      .select('rect')
      .sort((a, b) => {
        return d3.ascending(a.value, b.value)
      })
      .transition()
      // .delay((d, i) => {
      //   return i * 50
      // })
      .duration(1000)
      .attr('x', (d, i) => {
        return this.barChart.xScale(i)
      })
    this.barChart.svg.selectAll('.gbar')
      .select('text')
      .sort((a, b) => {
        return d3.ascending(a.value, b.value)
      })
      .transition()
      // .delay((d, i) => {
      //   return i * 50
      // })
      .duration(1000)
      .attr('x', (d, i) => {
        return this.barChart.xScale(i) + this.barChart.barPadding * 0.3
      })
  },
  drawLabel: function () {
    // 标题
    this.barChart.svg
      .append('text')
      .attr('x', this.barChart.divWidth / 2 - this.title.length)
      .attr('y', this.barChart.divHeight + this.barChart.padding.bottom * 1.7)
      .text(this.title)
    // y轴
    this.barChart.svg
      .append('text')
      .attr('x', this.barChart.padding.left)
      .attr('y', this.barChart.padding.top - 5)
      .text(this.yLabel)
    // x轴
    this.barChart.svg
      .append('text')
      .attr('x', this.barChart.divWidth + 5)
      .attr('y', this.barChart.divHeight)
      .text(this.xLabel)
  }
}

export {
  BarChart
}
